package juc.topic;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description 线程交替打印 12A34B56C。。。。5152Z
 * 一个线程打印数字，一个线程打印字母，交替打印1-52个字符
 * 使用 reentrantLock 与 condition 实现
 */
public class CrossPrint02 {
    private static final Lock lock = new ReentrantLock();
    private static final Condition printNumberCondition = lock.newCondition();
    private static final Condition printLetterCondition = lock.newCondition();
    private static boolean printNumber = true;

    public static void main(String[] args) {
        Thread printNumberThread = new Thread(() -> {
            for (int i = 1; i <= 52; i = i + 2) {
                //需要手动释放锁
                lock.lock();
                try {
                   //不是打印的数字，则等待
                    while (!printNumber) {
                       printNumberCondition.await();
                    }
                    System.out.print(i);
                    System.out.print(i + 1);
                    printNumber = false;// 打印切换标志
                    printLetterCondition.signal();// 唤醒等待的字谜线程
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }finally {
                    lock.unlock();
                }
            }
        });

        Thread printLetterThread = new Thread(() -> {
            for (char c = 'A'; c <= 'Z'; c++) {
                //获取锁，如果获取不到则等待 需要手动释放锁
                lock.lock();
                try {
                    //不是打印的字母，则等待
                    while (printNumber) {
                       printLetterCondition.await();
                    }
                    System.out.print(c);
                    printNumber = true;// 打印切换标志
                    printNumberCondition.signal();// 唤醒等待的数字线程
                } catch (Exception e) {
                    throw new RuntimeException(e);
                } finally {//需要手动释放锁
                    lock.unlock();
                }
            }

        });

        printLetterThread.start();
        printNumberThread.start();

        // 主进程等待子线程执行完毕
        try {
            printNumberThread.join();
            printLetterThread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }
    }

}
